25/08/2024 - 31/08/2024

26/08/2024 15:08

Note to self:
The IP of our fe01 machine is 192.168.102.46

Tried replacing the block RAM
b41836a984972897a5c013255488907c.png

For the most part, I let the autoconnection do it's thing. We do indeed see the board with lspci after this

[root@fe01 ~]# lspci -vv | grep -A 35 "Xilinx"
pcilib: sysfs_read_vpd: read failed: Input/output error
04:00.0 Serial controller: Xilinx Corporation Device 7024 (prog-if 01 [16450])
        Subsystem: Xilinx Corporation Device 0007
        Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx+
        Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
        Latency: 0, Cache Line Size: 64 bytes
        Interrupt: pin A routed to IRQ 36
        Region 0: Memory at f5ff0000 (32-bit, non-prefetchable) [size=64K]
        Capabilities: [40] Power Management version 3
                Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1+,D2+,D3hot+,D3cold-)
                Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
        Capabilities: [48] MSI: Enable+ Count=1/1 Maskable- 64bit+
                Address: 00000000fee00000  Data: 4073
        Capabilities: [60] Express (v2) Endpoint, MSI 00
                DevCap: MaxPayload 512 bytes, PhantFunc 0, Latency L0s <64ns, L1 unlimited
                        ExtTag+ AttnBtn- AttnInd- PwrInd- RBE+ FLReset- SlotPowerLimit 225.000W
                DevCtl: Report errors: Correctable- Non-Fatal+ Fatal+ Unsupported-
                        RlxdOrd+ ExtTag- PhantFunc- AuxPwr- NoSnoop+
                        MaxPayload 256 bytes, MaxReadReq 512 bytes
                DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr- TransPend-
                LnkCap: Port #0, Speed 5GT/s, Width x4, ASPM L0s, Exit Latency L0s unlimited, L1 unlimited
                        ClockPM- Surprise- LLActRep- BwNot- ASPMOptComp-
                LnkCtl: ASPM Disabled; RCB 64 bytes Disabled- CommClk+
                        ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
                LnkSta: Speed 5GT/s, Width x4, TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt-
                DevCap2: Completion Timeout: Range B, TimeoutDis-, LTR-, OBFF Not Supported
                DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis-, LTR-, OBFF Disabled
                LnkCtl2: Target Link Speed: 5GT/s, EnterCompliance- SpeedDis-
                         Transmit Margin: Normal Operating Range, EnterModifiedCompliance- ComplianceSOS-
                         Compliance De-emphasis: -6dB
                LnkSta2: Current De-emphasis Level: -6dB, EqualizationComplete-, EqualizationPhase1-
                         EqualizationPhase2-, EqualizationPhase3-, LinkEqualizationRequest-
        Capabilities: [100 v1] Device Serial Number 00-00-00-00-00-00-00-00
        Kernel driver in use: xdma
        Kernel modules: xdma

06:00.0 Ethernet controller: Broadcom Inc. and subsidiaries NetXtreme BCM5761 Gigabit Ethernet PCIe (rev 10)
        Subsystem: Broadcom Inc. and subsidiaries NetXtreme BCM5761 Gigabit Ethernet PCIe
[root@fe01 ~]#
[root@fe01 ~]# lspci -vv | grep -A 35 "Xilinx"
pcilib: sysfs_read_vpd: read failed: Input/output error
04:00.0 Serial controller: Xilinx Corporation Device 7024 (prog-if 01 [16450])
        Subsystem: Xilinx Corporation Device 0007
        Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx+
        Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
        Latency: 0, Cache Line Size: 64 bytes
        Interrupt: pin A routed to IRQ 36
        Region 0: Memory at f5ff0000 (32-bit, non-prefetchable) [size=64K]
        Capabilities: [40] Power Management version 3
                Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1+,D2+,D3hot+,D3cold-)
                Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
        Capabilities: [48] MSI: Enable+ Count=1/1 Maskable- 64bit+
                Address: 00000000fee00000  Data: 4073
        Capabilities: [60] Express (v2) Endpoint, MSI 00
                DevCap: MaxPayload 512 bytes, PhantFunc 0, Latency L0s <64ns, L1 unlimited
                        ExtTag+ AttnBtn- AttnInd- PwrInd- RBE+ FLReset- SlotPowerLimit 225.000W
                DevCtl: Report errors: Correctable- Non-Fatal+ Fatal+ Unsupported-
                        RlxdOrd+ ExtTag- PhantFunc- AuxPwr- NoSnoop+
                        MaxPayload 256 bytes, MaxReadReq 512 bytes
                DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr- TransPend-
                LnkCap: Port #0, Speed 5GT/s, Width x4, ASPM L0s, Exit Latency L0s unlimited, L1 unlimited
                        ClockPM- Surprise- LLActRep- BwNot- ASPMOptComp-
                LnkCtl: ASPM Disabled; RCB 64 bytes Disabled- CommClk+
                        ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
                LnkSta: Speed 5GT/s, Width x4, TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt-
                DevCap2: Completion Timeout: Range B, TimeoutDis-, LTR-, OBFF Not Supported
                DevCtl2: Completion Timeout: 50us to 50ms, TimeoutDis-, LTR-, OBFF Disabled
                LnkCtl2: Target Link Speed: 5GT/s, EnterCompliance- SpeedDis-
                         Transmit Margin: Normal Operating Range, EnterModifiedCompliance- ComplianceSOS-
                         Compliance De-emphasis: -6dB
                LnkSta2: Current De-emphasis Level: -6dB, EqualizationComplete-, EqualizationPhase1-
                         EqualizationPhase2-, EqualizationPhase3-, LinkEqualizationRequest-
        Capabilities: [100 v1] Device Serial Number 00-00-00-00-00-00-00-00
        Kernel driver in use: xdma
        Kernel modules: xdma

06:00.0 Ethernet controller: Broadcom Inc. and subsidiaries NetXtreme BCM5761 Gigabit Ethernet PCIe (rev 10)
        Subsystem: Broadcom Inc. and subsidiaries NetXtreme BCM5761 Gigabit Ethernet PCIe
[root@fe01 ~]#

Things seem to work

[root@fe01 tests]# ./load_driver.sh
xdma                   47131  0
Loading driver...
The Kernel module installed correctly and the xmda devices were recognized.
 DONE
[root@fe01 tests]# sudo ./run_test.sh
Info: Number of enabled h2c channels = 2
Info: Number of enabled c2h channels = 2
Info: The PCIe DMA core is memory mapped.
Info: Running PCIe DMA memory mapped write read test
      transfer size:  1024
      transfer count: 1
Info: Writing to h2c channel 0 at address offset 0.
Info: Writing to h2c channel 1 at address offset 1024.
Info: Wait for current transactions to complete.
sscanf() = 1, value = 0x00000400
sscanf() = 1, value = 0x00000400
sscanf() = 1, value = 0x00000000
sscanf() = 1, value = 0x00000400
sscanf() = 1, value = 0x00000001
sscanf() = 1, value = 0x00000001
device = /dev/xdma0_h2c_0, address = 0x00000000, size = 0x00000400, offset = 0x00000000, count = 1
device = /dev/xdma0_h2c_1, address = 0x00000400, size = 0x00000400, offset = 0x00000000, count = 1
host memory buffer = 0x19a0400
host memory buffer = 0xc50400
CLOCK_MONOTONIC reports 0.000038707 seconds (total) for last transfer of 1024 bytes
Transfer speed: 25.23 MB/s
CLOCK_MONOTONIC reports 0.000119755 seconds (total) for last transfer of 1024 bytes
Transfer speed: 8.15 MB/s
Info: Writing to h2c channel 0 at address offset 2048.
Info: Writing to h2c channel 1 at address offset 3072.
Info: Wait for current transactions to complete.
sscanf() = 1, value = 0x00000400
sscanf() = 1, value = 0x00000800
sscanf() = 1, value = 0x00000001
device = /dev/xdma0_h2c_0, address = 0x00000800, size = 0x00000400, offset = 0x00000000, count = 1
host memory buffer = 0x783400
sscanf() = 1, value = 0x00000400
sscanf() = 1, value = 0x00000c00
sscanf() = 1, value = 0x00000001
device = /dev/xdma0_h2c_1, address = 0x00000c00, size = 0x00000400, offset = 0x00000000, count = 1
host memory buffer = 0x85d400
CLOCK_MONOTONIC reports 0.000121881 seconds (total) for last transfer of 1024 bytes
Transfer speed: 8.01 MB/s
CLOCK_MONOTONIC reports 0.000101627 seconds (total) for last transfer of 1024 bytes
Transfer speed: 9.61 MB/s
Info: Reading from c2h channel 0 at address offset 0.
Info: Reading from c2h channel 1 at address offset 1024.
Info: Wait for the current transactions to complete.
sscanf() = 1, value = 0x00000400
sscanf() = 1, value = 0x00000400
sscanf() = 1, value = 0x00000001
device = /dev/xdma0_c2h_1, address = 0x00000400, size = 0x00000400, offset = 0x00000000, count = 1
sscanf() = 1, value = 0x00000400
host memory buffer = 0x2152000
sscanf() = 1, value = 0x00000000
sscanf() = 1, value = 0x00000001
device = /dev/xdma0_c2h_0, address = 0x00000000, size = 0x00000400, offset = 0x00000000, count = 1
host memory buffer = 0x1e17000
CLOCK_MONOTONIC reports 0.000024211 seconds (total) for last transfer of 1024 bytes
Transfer speed: 40.34 MB/s
CLOCK_MONOTONIC reports 0.000039237 seconds (total) for last transfer of 1024 bytes
Transfer speed: 24.89 MB/s
Info: Reading from c2h channel 0 at address offset 2048.
Info: Reading from c2h channel 1 at address offset 3072.
Info: Wait for the current transactions to complete.
sscanf() = 1, value = 0x00000400
sscanf() = 1, value = 0x00000800
sscanf() = 1, value = 0x00000001
device = /dev/xdma0_c2h_0, address = 0x00000800, size = 0x00000400, offset = 0x00000000, count = 1
host memory buffer = 0x8ea000
sscanf() = 1, value = 0x00000400
sscanf() = 1, value = 0x00000c00
sscanf() = 1, value = 0x00000001
device = /dev/xdma0_c2h_1, address = 0x00000c00, size = 0x00000400, offset = 0x00000000, count = 1
host memory buffer = 0x1ba8000
CLOCK_MONOTONIC reports 0.000026233 seconds (total) for last transfer of 1024 bytes
Transfer speed: 37.23 MB/s
CLOCK_MONOTONIC reports 0.000027351 seconds (total) for last transfer of 1024 bytes
Transfer speed: 35.70 MB/s
Info: Checking data integrity.
Info: Data check passed for address range 0 - 1024.
Info: Data check passed for address range 1024 - 2048.
Info: Data check passed for address range 2048 - 3072.
Info: Data check passed for address range 3072 - 4096.
Info: All PCIe DMA memory mapped tests passed.
Info: All tests in run_tests.sh passed.
[root@fe01 tests]#
[root@fe01 tests]# ./load_driver.sh
xdma                   47131  0
Loading driver...
The Kernel module installed correctly and the xmda devices were recognized.
 DONE
[root@fe01 tests]# sudo ./run_test.sh
Info: Number of enabled h2c channels = 2
Info: Number of enabled c2h channels = 2
Info: The PCIe DMA core is memory mapped.
Info: Running PCIe DMA memory mapped write read test
      transfer size:  1024
      transfer count: 1
Info: Writing to h2c channel 0 at address offset 0.
Info: Writing to h2c channel 1 at address offset 1024.
Info: Wait for current transactions to complete.
sscanf() = 1, value = 0x00000400
sscanf() = 1, value = 0x00000400
sscanf() = 1, value = 0x00000000
sscanf() = 1, value = 0x00000400
sscanf() = 1, value = 0x00000001
sscanf() = 1, value = 0x00000001
device = /dev/xdma0_h2c_0, address = 0x00000000, size = 0x00000400, offset = 0x00000000, count = 1
device = /dev/xdma0_h2c_1, address = 0x00000400, size = 0x00000400, offset = 0x00000000, count = 1
host memory buffer = 0x19a0400
host memory buffer = 0xc50400
CLOCK_MONOTONIC reports 0.000038707 seconds (total) for last transfer of 1024 bytes
Transfer speed: 25.23 MB/s
CLOCK_MONOTONIC reports 0.000119755 seconds (total) for last transfer of 1024 bytes
Transfer speed: 8.15 MB/s
Info: Writing to h2c channel 0 at address offset 2048.
Info: Writing to h2c channel 1 at address offset 3072.
Info: Wait for current transactions to complete.
sscanf() = 1, value = 0x00000400
sscanf() = 1, value = 0x00000800
sscanf() = 1, value = 0x00000001
device = /dev/xdma0_h2c_0, address = 0x00000800, size = 0x00000400, offset = 0x00000000, count = 1
host memory buffer = 0x783400
sscanf() = 1, value = 0x00000400
sscanf() = 1, value = 0x00000c00
sscanf() = 1, value = 0x00000001
device = /dev/xdma0_h2c_1, address = 0x00000c00, size = 0x00000400, offset = 0x00000000, count = 1
host memory buffer = 0x85d400
CLOCK_MONOTONIC reports 0.000121881 seconds (total) for last transfer of 1024 bytes
Transfer speed: 8.01 MB/s
CLOCK_MONOTONIC reports 0.000101627 seconds (total) for last transfer of 1024 bytes
Transfer speed: 9.61 MB/s
Info: Reading from c2h channel 0 at address offset 0.
Info: Reading from c2h channel 1 at address offset 1024.
Info: Wait for the current transactions to complete.
sscanf() = 1, value = 0x00000400
sscanf() = 1, value = 0x00000400
sscanf() = 1, value = 0x00000001
device = /dev/xdma0_c2h_1, address = 0x00000400, size = 0x00000400, offset = 0x00000000, count = 1
sscanf() = 1, value = 0x00000400
host memory buffer = 0x2152000
sscanf() = 1, value = 0x00000000
sscanf() = 1, value = 0x00000001
device = /dev/xdma0_c2h_0, address = 0x00000000, size = 0x00000400, offset = 0x00000000, count = 1
host memory buffer = 0x1e17000
CLOCK_MONOTONIC reports 0.000024211 seconds (total) for last transfer of 1024 bytes
Transfer speed: 40.34 MB/s
CLOCK_MONOTONIC reports 0.000039237 seconds (total) for last transfer of 1024 bytes
Transfer speed: 24.89 MB/s
Info: Reading from c2h channel 0 at address offset 2048.
Info: Reading from c2h channel 1 at address offset 3072.
Info: Wait for the current transactions to complete.
sscanf() = 1, value = 0x00000400
sscanf() = 1, value = 0x00000800
sscanf() = 1, value = 0x00000001
device = /dev/xdma0_c2h_0, address = 0x00000800, size = 0x00000400, offset = 0x00000000, count = 1
host memory buffer = 0x8ea000
sscanf() = 1, value = 0x00000400
sscanf() = 1, value = 0x00000c00
sscanf() = 1, value = 0x00000001
device = /dev/xdma0_c2h_1, address = 0x00000c00, size = 0x00000400, offset = 0x00000000, count = 1
host memory buffer = 0x1ba8000
CLOCK_MONOTONIC reports 0.000026233 seconds (total) for last transfer of 1024 bytes
Transfer speed: 37.23 MB/s
CLOCK_MONOTONIC reports 0.000027351 seconds (total) for last transfer of 1024 bytes
Transfer speed: 35.70 MB/s
Info: Checking data integrity.
Info: Data check passed for address range 0 - 1024.
Info: Data check passed for address range 1024 - 2048.
Info: Data check passed for address range 2048 - 3072.
Info: Data check passed for address range 3072 - 4096.
Info: All PCIe DMA memory mapped tests passed.
Info: All tests in run_tests.sh passed.
[root@fe01 tests]#

27/08/2024 17:42

Getting a midas python frontend running is fairly simple:

  1. Install midas package
cd $MIDASSYS/python
python setup.py install
cd $MIDASSYS/python
python setup.py install
  1. Copy and run example frontend:
cd $MIDASSYS/python/examples
cp basic_frontend.py /path/to/new/desired/frontend/location
cd $MIDASSYS/python/examples
cp basic_frontend.py /path/to/new/desired/frontend/location
  1. Run the frontend
python basic_frontend.py
python basic_frontend.py

It should appear on the midas webpage.


27/08/2024 18:56

Playing around, it seems like a python frontend will only poll at a max rate of ~100Hz

[root@dhcp-10-163-105-238 frontend_simulator]# python frontend.py
Loaded data from fake_data.txt: [1, 25344, 0, 6912, 268, 8716, -23208, 24865, 0, 0]...
Initialized zero buffer with 5 zeros.
Initialization complete
Running...
[DataSimulator-Python,INFO] Frontend has started run number 11
[DataSimulator-Python,INFO] Frontend has ended run number 11
Poll function was called 114 times.
Average interval between poll calls: 0.103159 seconds
[root@dhcp-10-163-105-238 frontend_simulator]# python frontend.py
Loaded data from fake_data.txt: [1, 25344, 0, 6912, 268, 8716, -23208, 24865, 0, 0]...
Initialized zero buffer with 5 zeros.
Initialization complete
Running...
[DataSimulator-Python,INFO] Frontend has started run number 11
[DataSimulator-Python,INFO] Frontend has ended run number 11
Poll function was called 114 times.
Average interval between poll calls: 0.103159 seconds

Output of this frontend code:

import midas
import midas.frontend
import midas.event
import numpy as np
import random
import time

class DataSimulatorEquipment(midas.frontend.EquipmentBase):
    def __init__(self, client, frontend):
        equip_name = "Python Data Simulator"
        default_common = midas.frontend.InitialEquipmentCommon()
        default_common.equip_type = midas.EQ_POLLED
        default_common.buffer_name = "SYSTEM"
        default_common.trigger_mask = 0
        default_common.event_id = 2
        default_common.period_ms = 100
        default_common.read_when = midas.RO_RUNNING
        default_common.log_history = 1
        
        midas.frontend.EquipmentBase.__init__(self, client, equip_name, default_common)
        print("Initialization complete")
        self.set_status("Initialized")

        self.frontend = frontend

    def readout_func(self):
        event = midas.event.Event()
        
        # Create a bank for zero buffer
        event.create_bank("CR00", midas.TID_SHORT, self.frontend.zero_buffer)
        
        # Simulate the addition of `data` in the periodic event
        data_block = []
        data_block.extend(self.frontend.data)
        
        # Append the simulated data to the event
        event.create_bank("CR00", midas.TID_SHORT, data_block)

        return event
    
    def poll_func(self):
        current_time = time.time()
        if current_time - self.frontend.last_poll_time >= self.frontend.poll_time:
            self.frontend.last_poll_time = current_time
            self.frontend.poll_count += 1
            self.frontend.poll_timestamps.append(current_time)
            return True  # Indicate that an event is available
        return False  # No event available yet

class DataSimulatorFrontend(midas.frontend.FrontendBase):
    def __init__(self):
        midas.frontend.FrontendBase.__init__(self, "DataSimulator-Python")
        
        # Data and zero buffer initialization
        self.data = []
        self.zero_buffer = []
        self.generator = random.Random()
        self.load_data_from_file("fake_data.txt")
        self.init_zero_buffer()

        # Polling variables
        self.poll_time = 0.1  # Poll time in seconds
        self.last_poll_time = time.time()
        self.poll_count = 0
        self.poll_timestamps = []

        self.add_equipment(DataSimulatorEquipment(self.client, self))

    def load_data_from_file(self, filename):
        try:
            with open(filename, 'r') as file:
                for line in file:
                    values = [int(value) for value in line.strip().split(',')]
                    self.data.extend(values)
            print(f"Loaded data from {filename}: {self.data[:10]}...")  # Display the first few values for verification
        except IOError as e:
            print(f"Error opening file: {e}")

    def init_zero_buffer(self):
        total_data_size = 5  # Adjust size as needed
        self.zero_buffer = [0] * total_data_size
        print(f"Initialized zero buffer with {total_data_size} zeros.")

    def begin_of_run(self, run_number):
        self.set_all_equipment_status("Running", "greenLight")
        self.client.msg(f"Frontend has started run number {run_number}")
        return midas.status_codes["SUCCESS"]

    def end_of_run(self, run_number):
        self.set_all_equipment_status("Finished", "greenLight")
        self.client.msg(f"Frontend has ended run number {run_number}")
        
        # Print poll function statistics at the end of the run
        self.print_poll_stats()

        return midas.status_codes["SUCCESS"]

    def frontend_exit(self):
        print("Frontend is exiting.")

    def print_poll_stats(self):
        if len(self.poll_timestamps) > 1:
            intervals = [self.poll_timestamps[i] - self.poll_timestamps[i-1] for i in range(1, len(self.poll_timestamps))]
            avg_interval = sum(intervals) / len(intervals)
            print(f"Poll function was called {self.poll_count} times.")
            print(f"Average interval between poll calls: {avg_interval:.6f} seconds")
        else:
            print(f"Poll function was called {self.poll_count} times. Not enough data for interval calculation.")

if __name__ == "__main__":
    with DataSimulatorFrontend() as my_fe:
        my_fe.run()
import midas
import midas.frontend
import midas.event
import numpy as np
import random
import time

class DataSimulatorEquipment(midas.frontend.EquipmentBase):
    def __init__(self, client, frontend):
        equip_name = "Python Data Simulator"
        default_common = midas.frontend.InitialEquipmentCommon()
        default_common.equip_type = midas.EQ_POLLED
        default_common.buffer_name = "SYSTEM"
        default_common.trigger_mask = 0
        default_common.event_id = 2
        default_common.period_ms = 100
        default_common.read_when = midas.RO_RUNNING
        default_common.log_history = 1
        
        midas.frontend.EquipmentBase.__init__(self, client, equip_name, default_common)
        print("Initialization complete")
        self.set_status("Initialized")

        self.frontend = frontend

    def readout_func(self):
        event = midas.event.Event()
        
        # Create a bank for zero buffer
        event.create_bank("CR00", midas.TID_SHORT, self.frontend.zero_buffer)
        
        # Simulate the addition of `data` in the periodic event
        data_block = []
        data_block.extend(self.frontend.data)
        
        # Append the simulated data to the event
        event.create_bank("CR00", midas.TID_SHORT, data_block)

        return event
    
    def poll_func(self):
        current_time = time.time()
        if current_time - self.frontend.last_poll_time >= self.frontend.poll_time:
            self.frontend.last_poll_time = current_time
            self.frontend.poll_count += 1
            self.frontend.poll_timestamps.append(current_time)
            return True  # Indicate that an event is available
        return False  # No event available yet

class DataSimulatorFrontend(midas.frontend.FrontendBase):
    def __init__(self):
        midas.frontend.FrontendBase.__init__(self, "DataSimulator-Python")
        
        # Data and zero buffer initialization
        self.data = []
        self.zero_buffer = []
        self.generator = random.Random()
        self.load_data_from_file("fake_data.txt")
        self.init_zero_buffer()

        # Polling variables
        self.poll_time = 0.1  # Poll time in seconds
        self.last_poll_time = time.time()
        self.poll_count = 0
        self.poll_timestamps = []

        self.add_equipment(DataSimulatorEquipment(self.client, self))

    def load_data_from_file(self, filename):
        try:
            with open(filename, 'r') as file:
                for line in file:
                    values = [int(value) for value in line.strip().split(',')]
                    self.data.extend(values)
            print(f"Loaded data from {filename}: {self.data[:10]}...")  # Display the first few values for verification
        except IOError as e:
            print(f"Error opening file: {e}")

    def init_zero_buffer(self):
        total_data_size = 5  # Adjust size as needed
        self.zero_buffer = [0] * total_data_size
        print(f"Initialized zero buffer with {total_data_size} zeros.")

    def begin_of_run(self, run_number):
        self.set_all_equipment_status("Running", "greenLight")
        self.client.msg(f"Frontend has started run number {run_number}")
        return midas.status_codes["SUCCESS"]

    def end_of_run(self, run_number):
        self.set_all_equipment_status("Finished", "greenLight")
        self.client.msg(f"Frontend has ended run number {run_number}")
        
        # Print poll function statistics at the end of the run
        self.print_poll_stats()

        return midas.status_codes["SUCCESS"]

    def frontend_exit(self):
        print("Frontend is exiting.")

    def print_poll_stats(self):
        if len(self.poll_timestamps) > 1:
            intervals = [self.poll_timestamps[i] - self.poll_timestamps[i-1] for i in range(1, len(self.poll_timestamps))]
            avg_interval = sum(intervals) / len(intervals)
            print(f"Poll function was called {self.poll_count} times.")
            print(f"Average interval between poll calls: {avg_interval:.6f} seconds")
        else:
            print(f"Poll function was called {self.poll_count} times. Not enough data for interval calculation.")

if __name__ == "__main__":
    with DataSimulatorFrontend() as my_fe:
        my_fe.run()

27/08/2024 18:57

To verify the above, I stripped down the frontend as much as I could. I.e. I just timed the polling for the example frontend and came to the same conclusion

[root@dhcp-10-163-105-238 frontend_simulator]# python example_frontend.py
Running...
[myfe_name,INFO] Frontend has seen start of run number 13
Run 13 Polling Statistics:
Total polls: 1471
Average interval: 0.013 s
Min interval: 0.010 s
Max interval: 3.992 s
[myfe_name,INFO] Frontend has seen end of run number 13
^CReceived Ctrl-C, aborting...
Goodbye from user code!
Midas shutdown
[root@dhcp-10-163-105-238 frontend_simulator]#
[root@dhcp-10-163-105-238 frontend_simulator]# python example_frontend.py
Running...
[myfe_name,INFO] Frontend has seen start of run number 13
Run 13 Polling Statistics:
Total polls: 1471
Average interval: 0.013 s
Min interval: 0.010 s
Max interval: 3.992 s
[myfe_name,INFO] Frontend has seen end of run number 13
^CReceived Ctrl-C, aborting...
Goodbye from user code!
Midas shutdown
[root@dhcp-10-163-105-238 frontend_simulator]#

I.e. with python frontends we can only poll at around 100Hz.